#!/usr/bin/env python
# encoding: utf-8
'''
@author: Excelsiorly
@license: (C) Copyright 2022, All Rights Reserved.
@contact: excelsiorly@qq.com
@file: 236. 二叉树的最近公共祖先.py
@time: 2022/1/7 17:05
@desc:
    - 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。
      百度百科中最近公共祖先的定义为：“对于有根树 T 的两个节点 p、q，
      最近公共祖先表示为一个节点 x，满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。”
    - https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-tree/
@解题思路：
    1. dfs
    2. dfs到某个结点的时候，有两种情况可以使其本身成为答案：
        a. p、q分布在其左右两个子树
        b. 其本身是p或者q，同时另一个分布在其左子树或者右子树
    3. 同235：https://leetcode-cn.com/problems/lowest-common-ancestor-of-a-binary-search-tree/
    4. Ot(n), Os(n)
'''
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def dfs(self, root, p, q):
            if not root: return False
            # 标志有无在左子树中找到p或q
            lson = self.dfs(root.left, p, q)
            # 标志有无在右子树中找到p或q
            rson = self.dfs(root.right, p, q)
            if (lson and rson) or ((root.val==p.val or root.val == q.val) and (lson or rson)):
                self.ans = root
            return lson or rson or (root.val==p.val or root.val == q.val)

    def lowestCommonAncestor(self, root, p, q):
        """
        :type root: TreeNode
        :type p: TreeNode
        :type q: TreeNode
        :rtype: TreeNode
        """
        self.ans = None
        self.dfs(root, p, q)
        return self.ans